<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>

    <body>
        <input id="file" type="file" />
        <button id="handleUpload">上传</button>

        <script type="module">
            const file = document.getElementById('file')
            let filename = ''
            file.addEventListener('change', async (e) => {
                const file = e.target.files[0]
                filename = file.name
            })

            const handleUpload = document.getElementById('handleUpload')
            handleUpload.addEventListener('click', async () => {
                const file = document.getElementById('file').files[0]
                const fileChunkList = createFileChunk(file, SIZE)
                const data = fileChunkList.map((item, index) => {
                    return {
                        chunk: item,
                        hash: filename + '_' + index,
                    }
                })
                uploadChunks(data)
            })

            /**
             * 请求接口封装
             */
            function request({
                url,
                method = "post",
                data,
                headers = {},
                requestList
            }) {
                return new Promise(resolve => {
                    const xhr = new XMLHttpRequest();
                    xhr.open(method, url);
                    Object.keys(headers).forEach(key =>
                        xhr.setRequestHeader(key, headers[key])
                    );
                    xhr.send(data);
                    xhr.onload = e => {
                        resolve({
                            data: e.target.response
                        });
                    };
                });
            }

            // 切片大小
            const SIZE = 10 * 1024 * 1024;
            function createFileChunk(file, size) {
                const chunkList = [];
                let cur = 0;
                while (cur < file.size) {
                    chunkList.push(file.slice(cur, cur + size));
                    cur += size;
                }
                return chunkList;
            }

            async function uploadChunks(data) {
                const requestList = data.map(({chunk,hash})=>{
                    const formData = new FormData();
                    // 解决中文文件名乱码问题
                    const encodedHash = encodeURIComponent(hash);
                    formData.append('file',chunk,encodedHash)
                    return formData
                }).map(formData=>{
                    return request({
                        url: 'http://localhost:3000/api/upload',
                        data: formData
                    })
                })
                await Promise.all(requestList)
                await mergeRequest()
            }
            async function mergeRequest(){
                await request({
                    url: 'http://localhost:3000/api/merge',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    data: JSON.stringify({
                        filename
                    })
                })
            }

            


        </script>
    </body>

</html>